# -*- coding: utf-8 -*-
"""
Macana XML-RPC Dispatcher for Taíno
Copyright (C) 2009, Joshua "jag" Ginsberg <jag@flowtheory.net

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
"""
import pydoc
import xmlrpclib
from taino.api import Component
from macana.api import IMacanaXMLRPCMethod

class SystemListMethods(Component):
    implements = IMacanaXMLRPCMethod
    component_id = 'net.skwx.macana.SystemListMethods'
    component_description = 'An implementation of system.listMethods'
    
    def get_method_name(self):
        """Returns the name of the method implemented."""
        return "system.listMethods"
    
    def get_arg_list(self):
        """Returns a list of XML-RPC argument types that the method expects."""
        return []
    
    def get_return_type(self):
        """Returns the XML-RPC type that this method returns."""
        return 'array'
    
    def authorize(self, request):
        """Performs an authority test to determine whether a request is
        authorized. Returns a boolean -- True for authorized, False for
        unauthorized."""
        return True
        
    def handle_request(self, request, *args):
        """Lists available methods on this listener."""
        return map(lambda tpl: tpl[1], IMacanaXMLRPCMethod.get_method_name())

class SystemMethodSignature(Component):
    implements = IMacanaXMLRPCMethod
    component_id = 'net.skwx.macana.SystemMethodSignature'
    component_description = 'An implementation of system.methodSignature'
    
    def get_method_name(self):
        """Returns the name of the method implemented."""
        return "system.methodSignature"
    
    def get_arg_list(self):
        """Returns a list of XML-RPC argument types that the method expects."""
        return ["string"]
    
    def get_return_type(self):
        """Returns the XML-RPC type that this method returns."""
        return "array"
    
    def authorize(self, request):
        """Performs an authority test to determine whether a request is
        authorized. Returns a boolean -- True for authorized, False for
        unauthorized."""
        return True
        
    def handle_request(self, request, method_name):
        """Takes in the name of a method and returns a list of XML-RPC types
        for the argument the given method requires. Returns fault -32602 if
        the method is not found."""
        match = filter(lambda tpl: tpl[1] == method_name,
                       IMacanaXMLRPCMethod.get_method_name())
        if match:
            component = IMacanaXMLRPCMethod.get_component_by_id(match[0][0])
            return [component.get_return_type] + component.get_arg_list()
        else:
            raise Fault, (self.INVALID_PARAMETERS_FAULT_CODE,
                           u'Method not found. Use system.listMethods to see available methods.')

class SystemMethodHelp(Component):
    implements = IMacanaXMLRPCMethod
    component_id = 'net.skwx.macana.SystemMethodHelp'
    component_description = 'An implementation of system.methodHelp'
    
    def get_method_name(self):
        """Returns the name of the method implemented."""
        return "system.methodHelp"
    
    def get_arg_list(self):
        """Returns a list of XML-RPC argument types that the method expects."""
        return ["string"]
    
    def get_return_type(self):
        """Returns the XML-RPC type that this method returns."""
        return "string"
    
    def authorize(self, request):
        """Performs an authority test to determine whether a request is
        authorized. Returns a boolean -- True for authorized, False for
        unauthorized."""
        return True
        
    def handle_request(self, request, method_name):
        """Takes in the name of a method and returns plain text documentation
        on how to use that method. Returns fault -32602 if the method is not
        found."""
        match = filter(lambda tpl: tpl[1] == method_name,
                       IMacanaXMLRPCMethod.get_method_name())
        if match:
            component = IMacanaXMLRPCMethod.get_component_by_id(match[0][0])
            return pydoc.getdoc(component.handle_request)
        else:
            raise Fault, (self.INVALID_PARAMETERS_FAULT_CODE,
                           u'Method not found. Use system.listMethods to see available methods.')

